package lucky.xiong.煞笔面试题.JUC.threadLocal.优雅关闭线程池;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author XiongJianLin
 * @date Created in 2024/12/5 15:12
 */
public class ThreadPoolShutDown {

    public static void main(String[] args) {
//        finalOK();
//        shutdown_test();
        shutdown_awaitTermination();
    }

    private static void finalOK() {
        ExecutorService executorService = Executors.newFixedThreadPool(1);

        try {

        } catch (Exception e) {


        } finally {
            /**
             * 启动有序关闭，执行之前提交的任务，但不接受新任务。
             * 线程池置为 SHUTDOWN 状态
             * 使用 awaitTermination 判断是否还在执行中。
             *
             * 如果已经SHUTDOWN ，再次调用该方法不会有任何影响
             */
            executorService.shutdown();
            /**
             * 此方法不会等待之前提交的任务完成执
             *  不接收新任务
             *  尝试停止所有正在运行的线程：但对于无法响应interrupt()信号的，可能仍然会继续执行。
             *  待执行任务会取消，并返回等待队列列表。
             *  该方法返回时，这些等待的任务将从任务中情空。
             * 线程池状态置为:STOP.
             */
            List<Runnable> runnable = executorService.shutdownNow();
            // 生产时关闭

            finalOK_shutdownAndAwaitTermination(executorService);
        }
    }

    // 来自JDK17 文档
    public static void finalOK_shutdownAndAwaitTermination(ExecutorService threadPool) {
        if (threadPool != null && !threadPool.isShutdown()) {
            threadPool.shutdown();
            try {
                if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                    threadPool.shutdownNow();
                    if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                        System.err.println("Pool did not terminate");
                    }
                }
            } catch (InterruptedException ie) {
                threadPool.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }


    private static void shutdown_test() {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
//        try{

        for (int i = 0; i < 10; i++) {
            System.out.println("第" + i + "次提交任务");
            threadPool.execute(new Task());

            if (i == 5) {
                threadPool.shutdown();
            }
        }
//        } catch (Exception e) {
//            System.out.println("抓到错误");
//        }


        // 如果上面不捕获异常，那么这里不会输出，线程内容会继续
        // 使用awaitTermination 参照shutdown_awaitTermination()
        System.out.println(Thread.currentThread().getName() + "\t" + "线程池状态：" + threadPool.isTerminated());

    }

    private static void shutdown_awaitTermination() {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        try {
            for (int i = 0; i < 10; i++) {
                System.out.println("第" + i + "次提交任务");
                threadPool.execute(new Task());

                if (i == 5) {
                    threadPool.shutdown();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            /**
             * 阻塞当前线程，直到超时或终止。
             * 任务未执行完成且也没到返回时间，下面的日志打印不会执行。
             *
             * 此时设置的5s，达到设置时间后，直接打印下方的日志。
             */
            boolean awaitTermination = threadPool.awaitTermination(5, TimeUnit.SECONDS);
            System.out.println("是否停止：" + awaitTermination);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        System.out.println(Thread.currentThread().getName() + "\t" + "线程池状态：" + threadPool.isTerminated());

    }
}

class Task implements Runnable {
    @Override
    public void run() {
        try {
            System.out.println("执行任务");
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
